package com.mainbo.modular.system.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.mainbo.core.shiro.SessionKey;
import com.mainbo.core.shiro.ShiroKit;
import com.mainbo.core.util.GetPinyinUtil;
import com.mainbo.modular.jms.JmsService;
import com.mainbo.modular.jms.MessageTypes;
import com.mainbo.modular.jms.model.OrgMessageVo;
import com.mainbo.modular.jms.model.OrganizationVo;
import com.mainbo.modular.system.dao.PtAreaMapper;
import com.mainbo.modular.system.dao.PtUserManagescopeMapper;
import com.mainbo.modular.system.model.*;
import com.mainbo.modular.system.dao.PtOrgMapper;
import com.mainbo.modular.system.model.meta.MetaUtils;
import com.mainbo.modular.system.model.meta.vo.Meta;
import com.mainbo.modular.system.model.vo.OrgVo;
import com.mainbo.modular.system.service.IPtOrgRelationshipService;
import com.mainbo.modular.system.service.IPtOrgService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.mainbo.modular.system.service.IPtResourcesService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 机构数据类 服务实现类
 * </p>
 *
 * @author moshang
 * @since 2020-02-21
 */
@Service
public class PtOrgServiceImpl extends ServiceImpl<PtOrgMapper, PtOrg> implements IPtOrgService {
    private final static Logger logger = LoggerFactory.getLogger(PtOrgServiceImpl.class);

    @Resource
    private PtAreaMapper areaMapper;
    @Resource
    private PtOrgMapper orgMapper;
    @Resource
    private PtUserManagescopeMapper userManagescopeMapper;
    @Resource
    private IPtOrgRelationshipService orgRelationshipService;
    @Resource
    private IPtResourcesService resourcesService;
    @Resource
    private JmsService jmsService;

    @Override
    public String getAreaNameById(Integer areaId) {
        List<String> list = new ArrayList<String>();
        StringBuffer sb = new StringBuffer();
        while (areaId != 0) {
            PtArea area = areaMapper.selectById(areaId);
            list.add(area.getAreaName());
            if (0 == area.getPid()) {
                break;
            }
            areaId = area.getPid();
        }
        Collections.reverse(list);
        for (String string : list) {
            sb.append(string);
        }
        return sb.toString();
    }

    @Override
    public List<PtOrg> getOrgByAreaId(Integer areaId, Integer type) {
        EntityWrapper<PtOrg> org = new EntityWrapper<>();
        org.like("area_ids","," + areaId +",");
        if (null == type) {
            org.or().eq("type",1).or().eq("type",2);
        } else {
           org. eq("type",1);// 学校、机构
        }
        org.eq("deleted",0);
        List<PtOrg> listAll = orgMapper.selectList(org);
        return listAll;
    }

    @Override
    public PtOrg listOrgList() {
        PtAccount account=ShiroKit.getSessionAttr(SessionKey.CURRENT_USER);
        if (StringUtils.isNotBlank(account.getOrgId())){
            PtOrg org=orgMapper.selectById(account.getOrgId());
            return org;
        }
        return orgMapper.listOrgList(account.getId()).get(0);
    }

    @Override
    public List<OrgVo> findList(PtOrg org) {
        EntityWrapper<PtOrg> entityWrapper=new EntityWrapper<>();

        if (StringUtils.isNotEmpty(org.getName())) {
            String searchSch = org.getName();
         entityWrapper.like("name",searchSch);
        }
        String areaids = org.getAreaIds();
        if (StringUtils.isNotEmpty(areaids)) {
            entityWrapper.like("area_ids",","+areaids+",");
        } else {
            entityWrapper.like("area_ids",","+org.getAreaId()+",");
        }
        entityWrapper.orderBy("sort asc, crt_dttm desc");
        entityWrapper.eq("deleted",0);
        List<PtOrg> orgs=orgMapper.selectList(entityWrapper);
        List<OrgVo> list = new ArrayList<OrgVo>();
        for (PtOrg o : orgs) {
            OrgVo vo = new OrgVo();
            BeanUtils.copyProperties(o, vo);
            Integer areaId = o.getAreaId();
            String areaName = getAreaNameById(areaId);
            vo.setAreaName(areaName);
            if (PtOrg.TP_SCHOOL == vo.getType()) {
                vo.setAccountId(getAccountId(vo.getId()));
            }
            list.add(vo);
        }
        return list;
    }

    @Override
    public Integer updateOrg(PtOrg org) {
        PtAccount current=ShiroKit.getSessionAttr(SessionKey.CURRENT_USER);
        if (StringUtils.isBlank(org.getSchHost())){
            String host= GetPinyinUtil.getPinYinHeadChar(org.getName()).toLowerCase();
            if (findByhost(host)!=null){
                org.setSchHost(host+1);
            }else {
                org.setSchHost(host);
            }
        }
        // 保存机构学段的关系
        if (org.getId() != null && Integer.valueOf(PtOrg.TP_SCHOOL).equals(org.getType())) {
            PtOrg oldOrg = orgMapper.selectById(org.getId());
            if (oldOrg != null && !oldOrg.getSchoolings().equals(org.getSchoolings())) {
                orgRelationshipService.deleteByOrgId(oldOrg.getId());
                Map<String, Object> savePhaseRelationList = this.getPhaseRelationData(org);
                org.setPhaseTypes((String) savePhaseRelationList.get("phaseStr"));
                this.batchInsertSchRelation(savePhaseRelationList, oldOrg);
            }
        }
        org.setLastupId(current.getId());

        //LoggerUtils.updateLogger(LoggerModule.ZZJG, "组织机构——修改机构，机构id：{}", model.getId());

        PtOrg organization = orgMapper.selectById(org.getId());
        if (organization != null && org.getAreaId() != null && !organization.getAreaId().equals(org.getAreaId())) {
            List<Integer> areaIds = getAreaIds(org.getAreaId());
            StringBuffer sb = new StringBuffer(",");
            for (Integer integer : areaIds) {
                sb.append(integer + ",");
            }
            org.setAreaIds(sb.toString());

            EntityWrapper<PtOrg> sonOrg = new EntityWrapper<>();// 变更所属区域的，把相应子部门所属区域变更
            sonOrg.eq("pid",org.getId());
            List<PtOrg> orgList = orgMapper.selectList(sonOrg);
            for (PtOrg son : orgList) {
                son.setAreaIds(sb.toString());
                son.setAreaId(org.getAreaId());
                orgMapper.updateById(son);
            }
        }
        if (StringUtils.isNotBlank(org.getImage()) && !org.getImage().equals(organization.getImage())) {
            resourcesService.deleteResources(organization.getImage());
            resourcesService.updateTmptResources(org.getImage());
        }
        return orgMapper.updateById(org);


    }
    @Override
    public List<Integer> getAreaIds(Integer areaId) {
        List<Integer> areaIds = new ArrayList<Integer>();
        while (areaId != null && areaId != 0) {
            areaIds.add(areaId);
            PtArea area = areaMapper.selectById(areaId);
            areaId = area.getPid();
        }
        Collections.reverse(areaIds);
        return areaIds;
    }
    @Override
    public void sendMessage(MessageTypes type, PtOrg org) {
        try {
            OrgMessageVo vo = new OrgMessageVo();
            vo.setMessageType(type.name());
            OrganizationVo orgVo = new OrganizationVo();
            BeanUtils.copyProperties(org, orgVo);
            vo.setOrganizationVo(orgVo);
            jmsService.sendMessage(vo);
        } catch (Exception e) {
            logger.error("发送消息失败，消息类型{}", type.name(), e);
        }
    }
    private String getAccountId(String orgId) {
        PtUserManagescope scope = new PtUserManagescope();
        scope.setOrgId(orgId);
        scope = userManagescopeMapper.selectOne(scope);
        return scope == null ? null : scope.getAccountId();
    }
    private   PtOrg findByhost(String host) {
        PtOrg param =new PtOrg();
        param.setSchHost(host);
        PtOrg organization=orgMapper.selectOne(param);
        return organization;
    }

    private Map<String, Object> getPhaseRelationData(PtOrg model) {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        if (model != null && Integer.valueOf(PtOrg.TP_SCHOOL).equals(model.getType())) {
            List<PtOrgRelationship> dataList = new ArrayList<PtOrgRelationship>();
            Meta meta = MetaUtils.getOrgTypeProvider().getMeta(model.getSchoolings());
            Map<Integer, List<Meta>> phaseGradeMap = MetaUtils.getOrgTypeProvider().listPhaseXzGradeMap(meta.getId());
            Set<Integer> keySet = phaseGradeMap.keySet();
            StringBuilder phaseStr = new StringBuilder(",");
            for (Integer phase : keySet) {
                phaseStr.append(phase).append(",");
                PtOrgRelationship or = new PtOrgRelationship();
                or.setPhaseId(phase);
                or.setSchooling(phaseGradeMap.get(phase).size());
                if (model.getId() != null) {
                    or.setOrgId(model.getId());
                }
                dataList.add(or);
            }
            dataMap.put("phaseStr", phaseStr.toString());
            dataMap.put("relationData", dataList);
        }
        return dataMap;
    }

    private void batchInsertSchRelation(Map<String, Object> savePhaseRelationList, PtOrg org) {
        if (org != null && Integer.valueOf(PtOrg.TP_SCHOOL).equals(org.getType())) {
            List<PtOrgRelationship> dataList = (List<PtOrgRelationship>) savePhaseRelationList
                    .get("relationData");
            for (PtOrgRelationship organizationRelationship : dataList) {
                if (organizationRelationship != null) {
                    organizationRelationship.setOrgId(org.getId());
                }
            }
            orgRelationshipService.insertBatch(dataList);
        }
    }
}
